package com.apestech.api.workflow.xml;

import com.apestech.framework.file.IdFile;
import com.apestech.framework.util.DBUtil;
import com.apestech.framework.util.LocalVariable;
import com.apestech.framework.xml.pub.ReadXml;
import com.apestech.framework.xml.pub.WriteXml;
import com.apestech.framework.xml.pub.core.ElementUtil;
import org.dom4j.*;

import java.util.List;

/**
 * 读取工作流结点工具
 *
 * @author hup
 * @create 2018-08-14-16:33
 */
public class ExtendNode extends ElementUtil {

    private ReadXml readxml;
    private Element root;
    private Element workRoot;
    private WriteXml write;
    private String fileName;
    private String file;

    public ExtendNode(String file) throws Exception {
        if(file==null || "".equals(file)){
            throw new Exception("文件不能为空！");
        }
        if(file.indexOf(":")<0){
            IdFile idfile=new IdFile(LocalVariable.getWorkflowDir(), file, DBUtil.getSysInfo().getFileSeparator(), "bpmn");
            idfile.getData();
            file=idfile.getResultFile();
            if(file==null){
                throw new Exception("该为非法文件，请检查路径！");
            }
        }
        this.file=file;
        this.readxml=new ReadXml();
        this.readxml.loadXmlFromFile(file);
        this.root= this.readxml.getRoot();
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public void write() throws Exception {
        workRoot=null;
        List<?> list=root.content();
        Element node=null;
        int len=list.size();
        for(int i=0; i<len; i++) {
            String scalss = list.get(i).getClass().getName();
            if (scalss.equals("org.dom4j.tree.DefaultElement")) {
                Element eml=(Element) list.get(i);
                if("process".equals(eml.getName())){
                    node=eml;
                    break;
                }
            }
        }
        if(node==null){
            throw new Exception("该文件为非法工作流XML，请检查！");
        }
        write=new WriteXml();
        write.setXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root></root>");
        write.createXml();
        addElement(node);
        list=node.content();
        len=list.size();
        for(int i=0; i<len; i++){
            String scalss=list.get(i).getClass().getName();
            if(scalss.equals("org.dom4j.tree.DefaultElement")){
                addElement((Element) list.get(i));
            }

        }
        if(fileName==null){
            fileName= file.substring(0, file.lastIndexOf("."))+".wf.bak.xml";
        }
        write.writeXml(fileName);
    }

    private void addElement(Element sour) throws Exception {
        if(sour==null) return;
        Element e=null;
        String nname=sour.getName();
        String name=sour.attributeValue("name");
        String nodeName="";
        if("sequenceFlow".equals(nname) || "exclusiveGateway".equals(nname)) return;
        if("process".equals(nname)){
            workRoot=write.getRoot().addElement("workflow");
            e=workRoot;
            Element ele=workRoot.addElement("form");
            setAttr(ele, "id", "表单路径");
            setAttr(ele, "api", "ESB中findOne方法名");
            setAttr(ele, "remark", "前端界面配置");
        } else {
            switch (nname){
                case "userTask":{
                    nodeName="task";
                    break;
                }
                case "serviceTask":{
                    nodeName="aut";
                    break;
                }
                case "callActivity":{
                    nodeName="subtask";
                    break;
                }
                case "startEvent":{
                    nodeName="start";
                    break;
                }
                case "endEvent":{
                    nodeName="end";
                    break;
                }
            }
            if(!(nodeName==null || "".equals(nodeName))){
                e=workRoot.addElement(nodeName);
            }
        }
        if(e!=null){
            String id=sour.attributeValue("id");
            setAttr(e, "id", id);
            if("startEvent".equals(nname)){
                name="开始事件";
            } else if("endEvent".equals(nname)){
                name="结束事件";
            }
            if(name==null || "".equals(name)){
                throw new Exception("id["+id+"]结点没有设定name属性，请补全！");
            }
            /*setAttr(e, "name", name);
            if(e.attributeValue("remark")==null){
                setAttr(e,"remark", name);
            }*/
            setAttr(e,"remark", name);
            addList(e, nodeName);
        }

    }

    private void addList(Element ele, String nodeName){
        switch (nodeName){
            case "start":{
                //setAttr(ele, "remark","每个结点能配置子结点信息，其它结点如要用可在这里COPY");
                Element e=ele.addElement("mapping");
                //setAttr(e, "remark", "配置后端要写入流程里的变量mapping，格式同ESB里的mapping格式");
                Element m=e.addElement("field");
                setAttr(m, "attrname", "字段ID");
                setAttr(m, "name", "字段中文名称");

                e=ele.addElement("content");
                //setAttr(e, "remark", "设置ESB前端界面要显示的字段mapping信息");
                m=e.addElement("field");
                setAttr(m, "attrname", "字段ID");
                setAttr(m, "target", "字段中文名称");

                e=ele.addElement("fields");
                //setAttr(e, "remark", "设置结点提交时前端要显示的字段，配置方法同前端字段配置");
                m=e.addElement("field");
                setAttr(m, "name", "字段ID");
                setAttr(m, "label", "字段中文名称");
                setAttr(m, "widget", "控件类型");
                setAttr(m, "required", "必填：波兰表达式");
                setAttr(m, "disabled", "是否可编辑：波兰表达式");

                e=ele.addElement("before");
                m=e.addElement("esb");
                setAttr(m, "id", "ESB执行的API地址");

                e=ele.addElement("after");
                m=e.addElement("esb");
                setAttr(m, "id", "ESB执行的API地址");
                break;
            }
            case "task":{
                Element e=ele.addElement("users");
                setAttr(e, "remark", "配置节点候选人");
                Element m=e.addElement("user");
                setAttr(m, "id", "人员ID");
                break;
            }
        }
    }

}
